//该文件是实现一个多线程调用生产者消费者模型，两线程代表对应角色
//生产者线程函数：1.获取一个任务 2. 将任务添加到生产队列
//消费者线程函数：1.执行一个任务 2.之后对任务的其它加工处理
//生产者消费者处理任务快慢的问题添加sleep调整

#include "blockqueue.hpp"
#include "Task.hpp"
#include <unistd.h>
#include <ctime>


void* Consumer(void* args)
{
    BlockQueue<Task> *bq=static_cast<BlockQueue<Task>*>(args);
    while (true)
    { 
        //usleep(1000);
        Task t=bq->pop();

        //t.Run();          
        t();            //或使用仿函数

        std::cout<<"处理任务: "<<t.GetTask()<<",运算结果: "<<t.GetResult()<<std::endl;
        //sleep(1);       
    }
}

//1.获取数据 2.添加到队列生产
void* Productor(void* args)
{   
    int len=opers.size();
    BlockQueue<Task> *bq=static_cast<BlockQueue<Task>*>(args);

    while(true)
    {   //1.获取数据，模拟生产者生产数据(放入任务队列前)
        int data1=rand()%10+1;              //[1,10]
        usleep(10);                         //获取数据花费的时间
        int data2=rand()%10;
        char op=opers[rand()%len];          //随机选取一个运算符
        Task t(data1,data2,op);             

        //2.添加到任务队列后
        bq->push(t);                        
        std::cout<<"生产了一个任务: "<<t.GetTask()<<std::endl;
        sleep(1);                           //一秒生产一个任务
    }
}


int main()
{
    srand(time(nullptr));
    //一个交易场所(特定结构的内存空间)
    BlockQueue<Task> *bq=new BlockQueue<Task>();

    pthread_t c[3],p[5];            //多生产者和多消费者

    for(int i=0;i<3;i++)
    {
        pthread_create(c+i,nullptr,Consumer,bq);
    }
    
    for(int i=0;i<5;i++)
    {
        pthread_create(p+i,nullptr,Productor,bq);
    }

    for(int i=0;i<3;i++)
    {
        pthread_join(c[i],nullptr);
    }   
    
    for(int i=0;i<5;i++)
    {
        pthread_join(p[i],nullptr);
    } 
    
    delete bq; 
    return 0;
}

/*
int main()
{
    //一个交易场所(特定结构的内存空间)
    BlockQueue<Task> *bq=new BlockQueue<Task>();

    //两种关系(生产者和消费者)，多生产多消费
    pthread_t c,p;

    pthread_create(&c,nullptr,Consumer,bq);
    pthread_create(&p,nullptr,Productor,bq);
    pthread_join(c,nullptr);
    pthread_join(p,nullptr);
    
    delete bq; 
    return 0;
}
*/
